/*
 * Tint Browser for Android
 *
 * Copyright (C) 2012 - to infinity and beyond J. Devauchelle and contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 3 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.cnbrowser.android.ui.managers;

import com.cnbrowser.android.R;
import com.cnbrowser.android.providers.BookmarksWrapper;
import com.cnbrowser.android.ui.activities.TintBrowserActivity;
import com.cnbrowser.android.ui.cbrowser.StartPageItemClickedListener;
import com.cnbrowser.android.ui.components.BadgedImageView;
import com.cnbrowser.android.ui.components.CustomWebView;
import com.cnbrowser.android.ui.fragments.BaseWebViewFragment;
import com.cnbrowser.android.ui.fragments.ChinaBrowserStartPageFragment;
import com.cnbrowser.android.ui.fragments.PhoneWebViewFragment;
import com.cnbrowser.android.ui.preferences.PreferencesActivity;
import com.cnbrowser.android.ui.runnables.HideToolbarsRunnable;
import com.cnbrowser.android.ui.views.LegacyPanelLayout;
import com.cnbrowser.android.ui.views.LegacyPanelLayout.PanelEventsListener;
import com.cnbrowser.android.ui.views.PhoneUrlBar;
import com.cnbrowser.android.ui.views.PhoneUrlBar.OnPhoneUrlBarEventListener;
import com.cnbrowser.android.ui.views.TabView;
import com.cnbrowser.android.ui.views.TabsScroller.OnRemoveListener;
import com.cnbrowser.android.utils.Constants;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.SparseArray;
import android.view.ActionMode;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.LinearLayout;

public class LegacyPhoneUIManager extends BasePhoneUIManager {

    private static final String TAG = "LegacyPhoneUIManager";
    private LegacyPanelLayout mPanel;

    private BadgedImageView mFaviconView;

    private LinearLayout mBottomBar;

    private ImageView mStartPage;
    private BadgedImageView mTabViewManagement;
    private ImageView mBookmarks;
    private ImageView mSetting;

    private ImageView mHome;

    private ImageView mExitFullScreen;

    private TabAdapter mAdapter;

    private SharedPreferences mPreferences;

    private ToolbarsAnimator mToolbarsAnimator;

    private HideToolbarsRunnable mHideToolbarsRunnable = null;

    static {
        sAnimationType = AnimationType.NONE;
    }

    public LegacyPhoneUIManager(TintBrowserActivity activity) {
        super(activity);

        mPreferences = PreferenceManager.getDefaultSharedPreferences(activity);

        mAdapter = new TabAdapter();
        mPanel.getTabsScroller().setAdapter(mAdapter);
    }

    @Override
    protected void setupUI() {
        mActionBar.hide();

        mPanel = (LegacyPanelLayout) mActivity.findViewById(R.id.legacy_panel_layout);

        mPanel.setPanelEventsListener(new PanelEventsListener() {

            @Override
            public void onPanelShown() {
                mPanel.getTabsScroller().snapToSelected(mCurrentTabIndex, true);
            }

            @Override
            public void onPanelHidden() { }
        });

        mExitFullScreen = (ImageView) mActivity.findViewById(R.id.ExitFullScreen);
        mExitFullScreen.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                toggleFullScreen();
            }
        });

        ImageView openTabView = (ImageView) mActivity.findViewById(R.id.BtnAddTab);
        openTabView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                addTab(true, PreferenceManager.getDefaultSharedPreferences(v.getContext()).
                        getBoolean(Constants.PREFERENCE_INCOGNITO_BY_DEFAULT, false));

                if (mPreferences.getBoolean(Constants.PREFERENCE_CLOSE_PANEL_ON_NEW_TAB, true)) {
                    mPanel.hidePanel();
                } else {
                    // Wait for the adapter/scoller to updated before scrolling to the new tab.
                    // Maybe find a better way to do this.
                    mPanel.postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            mPanel.getTabsScroller().snapToSelected(mCurrentTabIndex, true);
                        }
                    }, 50);
                }
            }
        });

        ImageView returnToTabView = (ImageView) mActivity.findViewById(R.id.BtnReturnToTabView);
        returnToTabView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mPanel.togglePanel();
            }
        });

        mBookmarks = (ImageView) mActivity.findViewById(R.id.BtnBookmarks);
        mBookmarks.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mBookmarks.isSelected()){
                    return;
                }
                addBookmarkFromCurrentPage();
            }
        });

        mProgressBar = (ProgressBar) mActivity.findViewById(R.id.WebViewProgress);
        mProgressBar.setIndeterminate(false);
        mProgressBar.setMax(100);
        mProgressBar.setVisibility(View.GONE);

        mUrlBar = (PhoneUrlBar) mActivity.findViewById(R.id.UrlBar);

        mUrlBar.setEventListener(new OnPhoneUrlBarEventListener() {

            @Override
            public void onVisibilityChanged(boolean urlBarVisible) {
                if (urlBarVisible) {
                    mUrlBar.showGoStopReloadButton();
                } else {
                    BaseWebViewFragment currentFragment = getCurrentWebViewFragment();

                    if ((currentFragment != null) &&
                            (currentFragment.isStartPageShown())){
                        mUrlBar.hideGoStopReloadButton();
                    }
                }
            }

            @Override
            public void onUrlValidated() {
                loadCurrentUrl();
            }

            @Override
            public void onGoStopReloadClicked() {
                if (mUrlBar.isUrlChangedByUser()) {
                    // Use the UIManager to load urls, as it perform check on them.
                    loadCurrentUrl();
                } else if (getCurrentWebView().isLoading()) {
                    getCurrentWebView().stopLoading();
                } else {
                    getCurrentWebView().reload();
                }
            }

            @Override
            public void onMenuVisibilityChanged(boolean isVisible) {
                mMenuVisible = isVisible;
            }
        });

        mUrlBar.setTitle(R.string.ApplicationName);
        mUrlBar.setSubtitle(R.string.UrlBarUrlDefaultSubTitle);

//        mFaviconView = (BadgedImageView) mActivity.findViewById(R.id.FaviconView);
//        mFaviconView.setOnClickListener(new OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                if (mUrlBar.isUrlBarVisible()) {
//                    mUrlBar.hideUrl();
//                } else {
//                    mPanel.togglePanel();
//                }
//            }
//        });

        mTopBar = (RelativeLayout) mActivity.findViewById(R.id.TopBar);
        mTopBar.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // Steal event from WebView.
            }
        });

        mBottomBar = (LinearLayout) mActivity.findViewById(R.id.BottomBar);
        mBottomBar.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // Steal event from WebView.
            }
        });

        mBack = (ImageView) mActivity.findViewById(R.id.BtnBack);
        mBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if ((!getCurrentWebViewFragment().isStartPageShown()) &&
                        (getCurrentWebView().canGoBack())) {
                    getCurrentWebView().goBack();
                    mPanel.hidePanel();
                }
            }
        });
        mBack.setEnabled(false);

        mForward = (ImageView) mActivity.findViewById(R.id.BtnForward);
        mForward.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if ((!getCurrentWebViewFragment().isStartPageShown()) &&
                        (getCurrentWebView().canGoForward())) {
                    getCurrentWebView().goForward();
                    setBookmarkState(getCurrentWebView().getUrl());
                    mPanel.hidePanel();
                }
            }
        });
        mForward.setEnabled(false);

        mStartPage = (ImageView) mActivity.findViewById(R.id.BtnStartPage);
        mStartPage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                loadHomePage();
            }
        });

        mTabViewManagement = (BadgedImageView) mActivity.findViewById(R.id.BtnTabViewMgr);
        mTabViewManagement.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mUrlBar.isUrlBarVisible()) {
                    mUrlBar.hideUrl();
                } else {
                    mPanel.togglePanel();
                }
            }
        });

        mSetting = (ImageView) mActivity.findViewById(R.id.BtnSetting);
        mSetting.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                //openBookmarksActivityForResult();
                Intent i = new Intent(mActivity, PreferencesActivity.class);
                mActivity.startActivity(i);
            }
        });

//        mHome = (ImageView) mActivity.findViewById(R.id.BtnHome);
//        mHome.setOnClickListener(new OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                mProgressBar.setProgress(0);
//                mProgressBar.setVisibility(View.GONE);
//                loadHomePage();
//                mPanel.hidePanel();
//            }
//        });

        mPanel.getTabsScroller().setOnRemoveListener(new OnRemoveListener() {

            @Override
            public void onRemovePosition(int position) {
                if (mFragmentsList.size() > 1) {
                    closeTabByIndex(position);
                } else {
                    loadHomePage();
                }
            }
        });

        mToolbarsAnimator = new ToolbarsAnimator(mTopBar, mBottomBar, null, null);
        startHideToolbarsThread();

        super.setupUI();
    }

    @Override
    public void addTab(String url, boolean openInBackground, boolean privateBrowsing) {
        super.addTab(url, openInBackground, privateBrowsing);

        updateUrlBar();
        mAdapter.notifyDataSetChanged();
    }

    @Override
    protected void closeLastTab() {
        super.closeLastTab();

        mAdapter.notifyDataSetChanged();
    }

    @Override
    protected void closeTabByIndex(int index) {
        super.closeTabByIndex(index);

        updateUrlBar();
        mAdapter.notifyDataSetChanged();
    }

    @Override
    protected void showCurrentTab(boolean notifyTabSwitched) {
        super.showCurrentTab(notifyTabSwitched);

        TabView currentTabView = mAdapter.getViewAt(mCurrentTabIndex);
        if (currentTabView != null) {
            currentTabView.setSelected(true);
        }
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        if (view == getCurrentWebView()) {
            mProgressBar.setProgress(0);
            mProgressBar.setVisibility(View.VISIBLE);

            mUrlBar.setUrl(url);

            mUrlBar.setGoStopReloadImage(R.drawable.ic_stop);

            updateBackForwardEnabled();

            setBookmarkState(url);
        }


        CustomWebView webview = (CustomWebView) view;
        PhoneWebViewFragment parent = (PhoneWebViewFragment) webview.getParentFragment();

        if (parent != null) {
            int index = mFragmentsList.indexOf(parent);
            if (index != -1) {
                TabView tabview = mAdapter.getViewAt(index);
                tabview.setFavicon(null);
            }
        }
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        if (view == getCurrentWebView()) {
            mProgressBar.setProgress(100);
            mProgressBar.setVisibility(View.GONE);

            mUrlBar.setUrl(url);

            mUrlBar.setGoStopReloadImage(R.drawable.ic_refresh);

            updateBackForwardEnabled();
        }
    }

    @Override
    public void onClientPageFinished(final CustomWebView view, String url) {
        super.onClientPageFinished(view, url);

        PhoneWebViewFragment parent = (PhoneWebViewFragment) view.getParentFragment();

        if ((parent != null) &&
                (!parent.isStartPageShown()) &&
                (!view.isLoading())) {
            int index = mFragmentsList.indexOf(parent);
            if (index != -1) {
                final TabView tabview = mAdapter.getViewAt(index);

                mPanel.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        tabview.setImage(view.capturePicture());
                    }
                }, 50);
            }
        }
    }

    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);

        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onReceivedIcon(WebView view, Bitmap icon) {
        // Don't call parent here, we don't need the parent behavior.
        CustomWebView webview = (CustomWebView) view;
        PhoneWebViewFragment parent = (PhoneWebViewFragment) webview.getParentFragment();

        if ((parent != null) &&
                (!parent.isStartPageShown())) {
            int index = mFragmentsList.indexOf(parent);
            if (index != -1) {
                TabView tabview = mAdapter.getViewAt(index);
                tabview.setFavicon(icon);
            }
        }
    }

    @Override
    public boolean onKeyBack() {
        if (!super.onKeyBack()) {
            if (mUrlBar.isUrlBarVisible()) {
                mUrlBar.hideUrl();

                return true;
            } else if (mPanel.isPanelShown()) {
                mPanel.hidePanel();
                return true;
            } else {
                CustomWebView currentWebView = getCurrentWebView();

                if ((currentWebView != null) &&
                        (currentWebView.canGoBack())) {
                    currentWebView.goBack();
                    setBookmarkState(currentWebView.getUrl());
                    return true;
                } else if (isHomePageStartPage() &&
                        !isStartPageShownOnCurrentTab()) {
                    loadHomePage();
                    setBookmarkState(null);
                    return true;
                } else if (isHomePageStartPage()) {
                    return popQuiteConfirm();
                }
            }
        }

        return false;
    }

    private boolean popQuiteConfirm() {
        final String[] selectItemNames = new String[]{"删除历史记录"};
        final boolean[] selectItemValues = new boolean[]{false};
        new AlertDialog.Builder(mActivity)
                .setIcon(R.drawable.ic_quesiton)
                .setTitle("您要退出吗?")
                .setMultiChoiceItems(selectItemNames, selectItemValues, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                        selectItemValues[which] = isChecked;
                    }
                })
                .setPositiveButton("确认", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        boolean deleteHistory = selectItemValues[0];
                        Log.d(TAG, String.valueOf(deleteHistory));
                        if (deleteHistory) {
                            BookmarksWrapper.clearHistoryAndOrBookmarks(mActivity.getContentResolver(), true, false);
                        }
                        mActivity.finish();
                    }
                })
                .setNegativeButton("取消", null)
                .create().show();
        return true;
    }

    @Override
    public boolean onKeySearch() {
        mUrlBar.showUrl();
        return true;
    }

    @Override
    public void onMenuVisibilityChanged(boolean isVisible) { }

    @Override
    public void onShowStartPage() {
        super.onShowStartPage();

        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onActionModeStarted(ActionMode mode) {
        mActionMode = mode;
    }

    @Override
    public void onActionModeFinished(ActionMode mode) {
        if (mActionMode != null) {
            mActionMode = null;

            InputMethodManager mgr = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.hideSoftInputFromWindow(null, 0);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if ((requestCode == TintBrowserActivity.ACTIVITY_BOOKMARKS) &&
                (resultCode == Activity.RESULT_OK)) {
            if (mPanel.isPanelShown()) {
                mPanel.hidePanel();
            }
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }

    @Override
    protected void setFullScreenFromPreferences() {
        boolean fullScreen = isFullScreen();

        Window win = mActivity.getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN;

        if (fullScreen) {
            winParams.flags |=  bits;
            mTopBar.setVisibility(View.GONE);
            mExitFullScreen.setVisibility(View.VISIBLE);
        } else {
            winParams.flags &= ~bits;
            mTopBar.setVisibility(View.VISIBLE);
            mExitFullScreen.setVisibility(View.GONE);
        }

        win.setAttributes(winParams);
    }

    @Override
    protected void updateUrlBar() {
        CustomWebView currentWebView;
        BaseWebViewFragment currentFragment = getCurrentWebViewFragment();

        if ((currentFragment != null) &&
                (currentFragment.isStartPageShown())) {
            currentWebView = null;
        } else {
            currentWebView = getCurrentWebView();
        }

        if (currentWebView != null) {
            String title = currentWebView.getTitle();
            String url = currentWebView.getUrl();
            Bitmap icon = currentWebView.getFavicon();

            if ((title != null) &&
                    (!title.isEmpty())) {
                mUrlBar.setTitle(title);
            } else {
                mUrlBar.setTitle(R.string.ApplicationName);
            }

            if ((url != null) &&
                    (!url.isEmpty())) {
                mUrlBar.setSubtitle(url);
                mUrlBar.setUrl(url);
            } else {
                mUrlBar.setSubtitle(R.string.UrlBarUrlDefaultSubTitle);
                mUrlBar.setUrl(null);
            }

            setApplicationButtonImage(icon);

            if (currentWebView.isLoading()) {
                mProgressBar.setProgress(currentWebView.getProgress());
                mProgressBar.setVisibility(View.VISIBLE);
                mUrlBar.setGoStopReloadImage(R.drawable.ic_stop);
            } else {
                mProgressBar.setVisibility(View.GONE);
                mUrlBar.setGoStopReloadImage(R.drawable.ic_refresh);
            }

            updateBackForwardEnabled();
        } else {
            mUrlBar.setTitle(R.string.ApplicationName);
            mUrlBar.setSubtitle(R.string.UrlBarUrlDefaultSubTitle);

            mProgressBar.setVisibility(View.GONE);

            mUrlBar.setUrl(null);
            mBack.setEnabled(false);
            mForward.setEnabled(false);
        }

        //mFaviconView.setValue(mFragmentsList.size());
        mTabViewManagement.setValue(mFragmentsList.size());

        mUrlBar.setPrivateBrowsingIndicator(currentFragment != null ? currentFragment.isPrivateBrowsingEnabled() : false);
    }

    @Override
    protected void createStartPageFragment() {
        mStartPageFragment = new ChinaBrowserStartPageFragment();
        mStartPageFragment.setOnStartPageItemClickedListener(new StartPageItemClickedListener() {
            @Override
            public void onItemClicked(String url) {
                loadUrl(url);
            }
        });
    }

    private void showTabByIndex(int index, boolean notifyTabSwitched) {
        PhoneWebViewFragment oldFragment = mFragmentsList.get(mCurrentTabIndex);
        oldFragment.getWebView().onPause();

        TabView oldTabView = mAdapter.getViewAt(mCurrentTabIndex);
        if (oldTabView != null) {
            oldTabView.setSelected(false);
        }

        mCurrentTabIndex = index;
        showCurrentTab(notifyTabSwitched);
    }

    public void hideToolbars() {
        if ((!mUrlBar.isUrlBarVisible()) &&
                (!getCurrentWebViewFragment().isStartPageShown()) &&
                (!mMenuVisible) &&
                (!getCurrentWebView().isLoading())) {
            setToolbarsVisibility(false);
        }

        mHideToolbarsRunnable = null;
    }

    public void showToolbars() {
        if (!mToolbarsAnimator.isToolbarsVisible()) {
            setToolbarsVisibility(true);
        }

        mHideToolbarsRunnable = null;
    }

    /**
     * Change the tool bars visibility.
     * @param setVisible If True, the tool bars will be shown.
     */
    private void setToolbarsVisibility(boolean setVisible) {
        if (setVisible) {
            if (!mToolbarsAnimator.isToolbarsVisible()) {
                mUrlBar.hideUrl();

                mToolbarsAnimator.startShowAnimation(false,false);
            }
        } else {
            if (mToolbarsAnimator.isToolbarsVisible()) {
                if (mHideToolbarsRunnable != null) {
                    mHideToolbarsRunnable.disable();
                }

                mUrlBar.hideUrl(mActionMode == null);

                mToolbarsAnimator.startHideAnimation();
            }
        }
    }

    private void startHideToolbarsThread() {
        if (mHideToolbarsRunnable != null) {
            mHideToolbarsRunnable.disable();
        }

//    	mHideToolbarsRunnable = new HideToolbarsRunnable(this, mToolbarsDisplayDuration * 1000);
        new Thread(mHideToolbarsRunnable).start();
    }

    @Override
    public void onMainActivityResume() {
        CustomWebView webView = getCurrentWebView();
        if (webView != null) {
            webView.resumeTimers();
            setBookmarkState(webView.getUrl());
        }
    }

    public void setBookmarkState(String url){
        if(BookmarksWrapper.isUrlBookmarked(mActivity.getContentResolver(), url)){
            mBookmarks.setSelected(true);
        }else{
            mBookmarks.setSelected(false);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
            hideToolbars();
        }else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            showToolbars();
        }
    }

    private class TabAdapter extends BaseAdapter {

        private SparseArray<TabView> mViews;

        public TabAdapter() {
            super();
            mViews = new SparseArray<TabView>();
        }

        @Override
        public int getCount() {
            return mFragmentsList.size();
        }

        @Override
        public PhoneWebViewFragment getItem(int position) {
            return mFragmentsList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public void notifyDataSetChanged() {
            mViews.clear();
            super.notifyDataSetChanged();
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            final TabView tabview = new TabView(mActivity);

            PhoneWebViewFragment fragment = getItem(position);

            if (fragment.isStartPageShown()) {
                tabview.setTitle(R.string.StartPageLabel);
                tabview.setFavicon(null);
            } else {
                CustomWebView webView = fragment.getWebView();

                tabview.setTitle(webView.getTitle());

                tabview.setFavicon(webView.getFavicon());
                tabview.setImage(webView.isLoading() ? null : webView.capturePicture());
            }

            tabview.setSelected(position == mCurrentTabIndex);

            tabview.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (tabview.isClose(v)) {
                        mPanel.getTabsScroller().animateOut(tabview);
                    } else {
                        showTabByIndex(position, true);
                        mPanel.hidePanel();
                    }
                }
            });

            mViews.put(position, tabview);

            return tabview;
        }

        public TabView getViewAt(int position) {
            return mViews.get(position);
        }

    }

}
